package com.naruto.thinkmgr.web;

import com.naruto.thinkmgr.bean.ApiResult;
import com.naruto.thinkmgr.bean.User;
import com.naruto.thinkmgr.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/")
public class IndexController {

    private Logger logger = LoggerFactory.getLogger(IndexController.class);

    //    @Reference(version = "1.0.0", check = false)
//    @InterfaceMethods(methods = {@Method(name = "addUser", retries = 0, timeout = 3000)})
//    @Autowired
//    private AppProperties appProperties;
    @Autowired
    private UserService userService;

    @Value("${app.druid.url}")
    private String druidUrl;

    @GetMapping("test")
    public String test() {
        Subject subject = SecurityUtils.getSubject();
        subject.checkPermission("user:add");
        return "index";
    }

    @GetMapping("test2")
    public String test2() {
        throw new NullPointerException();
    }

    @GetMapping("")
//    @RequiresPermissions("user:createx")
    public String index() {
        return "index";
    }

    @GetMapping("druid")
    public String druid(Model model) {
        logger.info("druidUrl={}",druidUrl);
        model.addAttribute("druidUrl", druidUrl);
        return "druid";
    }

    @GetMapping("login")
    public String login(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute("user");
        if (user != null) {
            return "redirect:/";
        }
        return "login";
    }

    @PostMapping("login")
    public String doLogin(String userName, char[] password, String rememberMe, HttpServletRequest request, RedirectAttributes model) {
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        token.setRememberMe(rememberMe != null);

        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            if (subject.isAuthenticated()) {
                User user = (User) subject.getPrincipal();
                request.getSession().setAttribute("user", user);
                SavedRequest savedRequest = WebUtils.getSavedRequest(request);//获取以保存的要跳转的目标url
                if (savedRequest != null && savedRequest.getRequestUrl() != null) {
                    logger.info("redirecti to " + savedRequest.getRequestUrl());
                    return "redirect:" + savedRequest.getRequestUrl();
                } else {
                    return "redirect:/";
                }
            }
        } catch (Exception e) {
            logger.error("login fail", e);
            String loginFailMsg = "登录失败";
            String exName = e.getClass().getName();
            if (e instanceof IncorrectCredentialsException) {
                loginFailMsg = "用户名或密码错误";
            } else if (e instanceof LockedAccountException) {
                loginFailMsg = "账户被锁定";
            } else if (e instanceof DisabledAccountException) {
                loginFailMsg = "账户被禁用";
            } else if (e instanceof ExcessiveAttemptsException) {
                loginFailMsg = "登录失败次数过多，请稍后重试";
            } else if (e instanceof ExpiredCredentialsException) {
                loginFailMsg = "凭证已过期";
            } else if (e instanceof AuthenticationException) {
                loginFailMsg = e.getMessage();
            }
            model.addFlashAttribute("loginFailMsg", loginFailMsg);
        }
        return "redirect:/login";
    }

    @GetMapping("logout")
    public String logout() {
        return "redirect:login";
    }

    @GetMapping("updatePasswordPage")
    public String updatePasswordPage() {
        return "updatePassword";
    }

    @PutMapping("updatePassword")
    @ResponseBody
    public ApiResult updatePassword(char[] oldPassword, char[] newPassword) {
        User dbUser = this.userService.getUserById(1);
        String salt = dbUser.getUserName();
        SimpleHash shOld = new SimpleHash("md5", ByteSource.Util.bytes(oldPassword), salt, 2);
        String hashOldPassword = shOld.toHex();
        if (!dbUser.getPassword().equals(hashOldPassword)) {
            throw new IllegalStateException("原密码不正确");
        }
        //校验新密码是否符合规则?

        SimpleHash sh = new SimpleHash("md5", ByteSource.Util.bytes(newPassword), salt, 2);
        String hashPassword = sh.toHex();
        dbUser.setPassword(hashPassword);
        this.userService.updatePassword(dbUser);

        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        return new ApiResult(10, "成功，请使用新密码重新登录。");
    }
}
